#pragma once

#include "../umlmodel_global.h"

#include <memory>
#include <vector>

#include "../umlcore/PartialElement.h"

using std::make_shared;
using std::shared_ptr;
using std::vector;

namespace uml {
class InteractionFragment;
class Message;

/// <summary>
/// MessageEnd
/// MessageEnd is an abstract specialization of NamedElement that represents what
/// can occur at the end of a Message.
/// </summary>
class UMLMODEL_EXPORT MessageEnd : public PartialElement {

public: // JsonSerializable override
    void fromJson(const QJsonObject& json, QStringList& errorList) override;
    void toJson(QJsonObject& json) override;

public: // Methods
    /// <summary>
    /// oppositeEnds
    /// This query returns a set including the MessageEnd (if exists) at the opposite
    /// end of the Message for this MessageEnd.
    /// </summary>
    virtual shared_ptr<vector<MessageEnd>> oppositeEnds() const;

    /// <summary>
    /// isSend
    /// This query returns value true if this MessageEnd is a sendEvent.
    /// </summary>
    virtual bool isSend() const;

    /// <summary>
    /// isReceive
    /// This query returns value true if this MessageEnd is a receiveEvent.
    /// </summary>
    virtual bool isReceive() const;

    /// <summary>
    /// enclosingFragments
    /// This query returns a set including the enclosing InteractionFragment this
    /// MessageEnd is enclosed within.
    /// </summary>
    virtual shared_ptr<vector<InteractionFragment>> enclosingFragments() const;

public: // Properties
    /// <summary>
    /// message getter
    /// References a Message.
    /// </summary>
    shared_ptr<Message> message() const;

    /// <summary>
    /// message setter
    /// References a Message.
    /// </summary>
    void setMessage(shared_ptr<Message> value);

private: // Fields
    /// <summary>
    /// message
    /// References a Message.
    /// </summary>
    shared_ptr<Message> message_;

};

} // namespace uml
